﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.ComponentModel;
using TestHarnessWebRole.Data;
using System.Data.Services.Client;
using Microsoft.WindowsAzure.StorageClient;
using AntsCode.StorageClientExtensions;

namespace TestHarnessWebRole
{
    public partial class TestBlock : System.Web.UI.UserControl
    {
        private bool singleInitialised = false;
        private ExecutionTimer timer = new ExecutionTimer();
        private List<TableServiceRequest> requests;

        public TestBlock()
        {
            this.ContinuationToken = null;
            this.ShowContinuationToken = false;
            this.requests = new List<TableServiceRequest>();
        }
            
        protected void Page_Load(object sender, EventArgs e)
        {
            this.TitleNode.InnerText = this.Title;
            this.CodeNode.InnerText = this.Code;   
        }

        public string Title { get; set; }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public string Code
        {
            get;
            set;
        }

        public void RunQuery<T>(TestTableServiceContext context, IQueryable<T> query)
        {
            context.SendingRequest += OnSendingRequest;

            XTableServiceQuery<T> tsQuery = (XTableServiceQuery<T>)query;
            tsQuery.ContinuationToken = this.ContinuationToken;

            timer.StartTimer();
            var data = query.ToList();
            timer.EndTimer();

            this.ContinuationToken = tsQuery.ContinuationToken;

            if (this.ContinuationToken != null && this.ShowContinuationToken)
            {
                this.ContinuationTokenBlock.Visible = true;
                this.ContinuationTokenLabel.InnerText = "{ NextPartitionKey = \"" + this.ContinuationToken.NextPartitionKey + "\", " +
                    "NextRowKey = \"" + this.ContinuationToken.NextRowKey + "\" }";
            }

            this.ResultsGrid.DataSource = data;
            this.ResultsGrid.DataBind();
            this.ExecutionTimeNode.InnerText = timer.ExecutionTime;

            this.QueryGrid.DataSource = this.requests;
            this.QueryGrid.DataBind();

            context.SendingRequest -= OnSendingRequest;
        }

        public void InitSingle(TestTableServiceContext context)
        {
            context.SendingRequest += OnSendingRequest;
            timer.StartTimer();
            singleInitialised = true;
        }

        public void RunSingle(TestTableServiceContext context, object entity)
        {
            if (!singleInitialised)
            {
                throw new ApplicationException("You must call InitSingle() before calling RunSingle()");
            }

            List<object> entities = new List<object>();
            entities.Add(entity);

            if (entity != null)
            {
                this.ResultsGrid.DataSource = entities;
                this.ResultsGrid.DataBind();
            }
            timer.EndTimer();

            this.ExecutionTimeNode.InnerText = timer.ExecutionTime;

            this.QueryGrid.DataSource = this.requests;
            this.QueryGrid.DataBind();

            context.SendingRequest -= OnSendingRequest;
            singleInitialised = false;
        }

        private void OnSendingRequest(object sender, XTableServiceSendingRequestEventArgs e)
        {
            this.requests.Add(new TableServiceRequest()
            {
                AsyncOrder = e.AsyncOrder,
                Request = Uri.UnescapeDataString(e.RequestUri.AbsoluteUri)
            });
        }

        private class TableServiceRequest
        {
            public int AsyncOrder { get; set; }
            public string Request { get; set; }
        }

        public ContinuationToken ContinuationToken
        {
            get;
            set;
        }

        public bool ShowContinuationToken
        {
            get;
            set;
        }
    }
}